package com.smh.demo1.a40;

import org.springframework.beans.factory.annotation.Value;
import org.springframework.beans.factory.config.BeanExpressionContext;
import org.springframework.beans.factory.config.DependencyDescriptor;
import org.springframework.context.annotation.AnnotationConfigUtils;
import org.springframework.context.support.GenericApplicationContext;
import org.springframework.stereotype.Component;

import java.lang.reflect.Field;

/**
 * @author shiminghui
 * @date 2025/5/10 11:25
 * @description: TODO
 */
public class A40 {
    public static void main(String[] args) throws NoSuchFieldException {
        // 模拟一下@Value注解的解析过程
        GenericApplicationContext context = new GenericApplicationContext();

        // 注册一些注解处理器
        AnnotationConfigUtils.registerAnnotationConfigProcessors(context);

        context.registerBean("bean2", Bean2.class);
//        context.registerBean("bean1", Bean1.class);
//        context.registerBean("bean3", Bean3.class);
//        context.registerBean("bean4", Bean4.class);

        context.refresh();
/*        System.out.println(context.getBean(Bean1.class).value);
        System.out.println(context.getBean(Bean2.class).value);
        System.out.println(context.getBean(Bean3.class).value);
        System.out.println(context.getBean(Bean4.class).value);*/

//        test1(context);
//        test2(context);
//        test3(context);
        test4(context);

        // 数据类型转换


    }

    private static void test4(GenericApplicationContext context) throws NoSuchFieldException {

        Field field = Bean4.class.getDeclaredField("value");
        DependencyDescriptor dd = new DependencyDescriptor(field, false);
        String value = dd.getAnnotation(Value.class).value();

        // 解析${}
        String s = context.getEnvironment().resolvePlaceholders(value);
        System.out.println(s);

        // 解析#{}
        Object o1 = context.getBeanFactory().getBeanExpressionResolver().evaluate(s, new BeanExpressionContext(context.getBeanFactory(), null));
        System.out.println(o1);

        //  数据类型转换
        Object o = context.getDefaultListableBeanFactory().getTypeConverter().convertIfNecessary(o1, dd.getDependencyType());
        System.out.println(o);
        System.out.println(o.getClass());

    }

    private static void test3(GenericApplicationContext context) throws NoSuchFieldException {

        Field field = Bean3.class.getDeclaredField("value");
        DependencyDescriptor dd = new DependencyDescriptor(field, false);
        String value = dd.getAnnotation(Value.class).value();

        // 解析${}
        String s = context.getEnvironment().resolvePlaceholders(value);
        System.out.println(s);

        // 解析#{}
        Object o1 = context.getBeanFactory().getBeanExpressionResolver().evaluate(s, new BeanExpressionContext(context.getBeanFactory(), null));
        System.out.println(o1);

        //  数据类型转换
        Object o = context.getDefaultListableBeanFactory().getTypeConverter().convertIfNecessary(o1, dd.getDependencyType());
        System.out.println(o);
        System.out.println(o.getClass());

    }

    private static void test2(GenericApplicationContext context) throws NoSuchFieldException {
        Field declaredField = Bean1.class.getDeclaredField("age");
        DependencyDescriptor dd = new DependencyDescriptor(declaredField, false);
        String value = dd.getAnnotation(Value.class).value();
        System.out.println(value);

        // 解析${}
        String s = context.getEnvironment().resolvePlaceholders(value);

        //  数据类型转换
        Object o = context.getDefaultListableBeanFactory().getTypeConverter().convertIfNecessary(s, dd.getDependencyType());
        System.out.println(o);
        System.out.println(o.getClass());

    }

    private static void test1(GenericApplicationContext context) throws NoSuchFieldException {
        Field field = Bean1.class.getDeclaredField("value");
        DependencyDescriptor dd1 = new DependencyDescriptor(field, false);
        Value annotation = dd1.getAnnotation(Value.class);
        String value = annotation.value();
        System.out.println(value);

        // 解析${}
        String s = context.getEnvironment().resolvePlaceholders(value);
        System.out.println(s);
    }

    static class Bean1 {
        @Value("${JAVA_HOME}")
        private String value;
        @Value("18")
        private int age;
    }

    @Component("bean2")
    static class Bean2 {
        @Value("${JAVA_HOME}")
        private String value;
    }

    static class Bean3 {
        @Value("#{@bean2}")   // SpringEL表达式, @bean2是获取名为bean2的bean
        private Bean2 value;
    }

    static class Bean4 {
        @Value("#{'hello,'+ '${JAVA_HOME}'}")
        private String value;
    }

}
